package com.aabte.design.pattern.creational.singleton;


import java.io.*;
import java.lang.reflect.Constructor;

public class Test {

    public static void main(String[] args) throws Exception {

        // testLazySingleton();
        // testSerializable();

        // testReflect();

        System.out.println("program end.");

    }

    public static void testReflect() throws Exception {
        HungrySingleton instance = HungrySingleton.getInstance();

        Constructor<HungrySingleton> constructor = HungrySingleton.class.getDeclaredConstructor();
        constructor.setAccessible(true);
        HungrySingleton hungrySingleton = constructor.newInstance();

        System.out.println(instance);
        System.out.println(hungrySingleton);
        System.out.println(hungrySingleton == instance);
    }

    public static void testSerializable() throws Exception {
        HungrySingleton instance = HungrySingleton.getInstance();
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singletonFile"));
        oos.writeObject(instance);

        File singletonFile = new File("singletonFile");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(singletonFile));
        HungrySingleton newInstance = (HungrySingleton)ois.readObject();

        System.out.println(instance);
        System.out.println(newInstance);
        System.out.println(newInstance == instance);
    }

    public static void testLazySingleton(){
        Thread thread1 = new Thread(new T());
        Thread thread2 = new Thread(new T());

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    static class T implements Runnable{

        public void run() {
            LazySingleton lazySingleton = LazySingleton.getInstance();
            System.out.println(Thread.currentThread().getName() + "   " + lazySingleton);
        }
    }


}
